package com.reformer.commons.utils;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * zip文件工具类
 *
 * @author sdc
 */
public class ZipFileUtil {
    /**
     * 读取压缩文件中的子文件
     *
     * @param zipFile
     * @param childFileName 子文件名
     * @return
     * @throws Exception
     */
    public static String readTxtFileInZip(File zipFile, String childFileName) throws Exception {
        int BUFFER = 2048;
        ZipFile zf = null;
        InputStream in = null;
        // ZipInputStream zin = null;
        try {
            Charset gbk = Charset.forName("GBK");
            zf = new ZipFile(zipFile, gbk);
            in = new BufferedInputStream(new FileInputStream(zipFile), BUFFER);
            // zin = new ZipInputStream(in,gbk);
            ZipEntry ze;
            Enumeration<? extends ZipEntry> e = zf.entries();
            while (e.hasMoreElements()) {
                ze = e.nextElement();
                if (!ze.isDirectory()) {
//                    System.err.println("file - " + ze.getName() + " : " + ze.getSize() + " bytes");
                    long size = ze.getSize();
                    if (size > 0 && ze.getName().equals(childFileName)) {
                        BufferedReader br = null;
                        try {
//                            System.out.println(ze.getName());
                            br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze), gbk));
                            // br = new BufferedReader(new
                            // InputStreamReader(zin,"gbk"));
                            String line;
                            StringBuffer sb = new StringBuffer();
                            while ((line = br.readLine()) != null) {
                                sb.append(line);
                                sb.append(System.lineSeparator());
                            }
                            return sb.toString().trim();
                        } finally {
                            if (br != null)
                                br.close();
                        }
                    }
                }
            }
        } finally {
            if (in != null)
                in.close();
            if (zf != null)
                zf.close();
        }
        return null;
    }

    /**
     * 将输入流压缩成字节
     * @param filenames
     * @param inputStreams
     * @return
     * @throws IOException
     */
    public static byte[] compressToBytes(String[] filenames, InputStream[] inputStreams) throws IOException {
        File file = File.createTempFile("tempkey", ".zip");
        try(ZipOutputStream zos = new ZipOutputStream (new CheckedOutputStream(new FileOutputStream(file), new CRC32()))){
            byte[] buffer = new byte[1024];
            for (int i = 0; i < filenames.length; i++) {
                try(InputStream inputStream = inputStreams[i]){
                    ZipEntry zipEntry = new ZipEntry(filenames[i]);
                    zos.putNextEntry(zipEntry);
                    int size;
                    while ((size = inputStream.read(buffer, 0, buffer.length)) > 0) {
                        zos.write(buffer, 0, size);
                    }
                    zos.closeEntry();
                }
            }
        }
        byte[] bytes;
        try (FileInputStream fileInputStream = new FileInputStream(file)){
            bytes = new byte[fileInputStream.available()];
            fileInputStream.read(bytes);
        }
        file.delete();
        return bytes;
    }

    /**
     * 压缩多个文件
     * @param savePath
     * @param saveFile
     * @param files
     * @throws IOException
     */
    public static void compressToFile(String savePath, String saveFile, File[] files) throws IOException {
        try(ZipOutputStream zos = new ZipOutputStream (new CheckedOutputStream(new FileOutputStream(new File(savePath, saveFile)), new CRC32()))){
            byte[] buffer = new byte[1024];
            for (int i = 0; i < files.length; i++) {
                try (InputStream inputStream = new FileInputStream(files[i])) {
                    ZipEntry zipEntry = new ZipEntry(files[i].getName());
                    zos.putNextEntry(zipEntry);
                    int size;
                    while ((size = inputStream.read(buffer, 0, buffer.length)) > 0) {
                        zos.write(buffer, 0, size);
                    }
                    zos.closeEntry();
                }
            }
        }
    }

//    public static void main(String[] args) throws Exception {
////        System.out.println(readTxtFileInZip(new File("F:\\study\\pay\\支付宝\\对账\\20889119146736650156_20160911.csv.zip"), "20889119146736650156_20160911_业务明细.csv"));
//        File f1= new File("D:\\tools\\mybatis_tools\\autocode\\com\\rfca\\dao\\UserMapper.java");
//        File f2=new File("D:\\tools\\mybatis_tools\\autocode\\com\\rfca\\dao\\UserMapper - 副本.java");
////        compressToFile("D:\\tools\\mybatis_tools\\autocode\\com\\rfca\\dao","demo.zip",new File[]{f1,f2});
//        byte[] bytes = compressToBytes(new String[]{"a.java", "b.java"}, new InputStream[]{new FileInputStream(f1), new FileInputStream(f2)});
//        FileOutputStream fos = new FileOutputStream("D:\\tools\\mybatis_tools\\autocode\\com\\rfca\\dao\\赝作.zip");
//        fos.write(bytes);
//        fos.close();
//    }

}
